package v1

import (
	"github.com/gin-gonic/gin"
	"go-programming-tour-book/blog_service/global"
	"go-programming-tour-book/blog_service/internal/service"
	"go-programming-tour-book/blog_service/pkg/app"
	"go-programming-tour-book/blog_service/pkg/convert"
	"go-programming-tour-book/blog_service/pkg/errcode"
)

type Article struct {
}

func NewArticle() Article {
	return Article{}
}

func (a Article) Get(ctx *gin.Context) {

}

// List 获取多个文章
// @Summary 获取多个文章
// @Produce json
// @Param name query string false "文章名称" maxlength(100)
// @Param state query int false "状态" Enums(0, 1) default(1)
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} model.ArticleSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/Articles [get]
func (a Article) List(ctx *gin.Context) {
	param := service.ArticleListRequest{}
	response := app.NewResponse(ctx)
	//入参校验和绑定
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		global.Logger.Errorf(ctx, "app.BindAndValid err: %v\n", errs)
		errRsp := errcode.InvalidParams.WithDetails(errs.Errors()...)
		response.ToErrorResponse(errRsp)
		return
	}

	svc := service.New(ctx.Request.Context())
	pager := app.Pager{
		Page:     app.GetPage(ctx),
		PageSize: app.GetPageSize(ctx),
	}
	//获取文章总数
	totalRows, err := svc.CountArticle(&service.CountArticleRequest{
		Title:         param.Title,
		Desc:          param.Desc,
		Content:       param.Content,
		CoverImageUrl: param.CoverImageUrl,
		State:         param.State,
	})
	if err != nil {
		global.Logger.Errorf(ctx, "svc.CountArticle err: %v", err)
		response.ToErrorResponse(errcode.ErrorCountArticleFail)
		return
	}

	//获取文章列表
	articles, err := svc.GetArticleList(&param, &pager)
	if err != nil {
		global.Logger.Errorf(ctx, "svc.GetArticleList err: %v", err)
		response.ToErrorResponse(errcode.ErrorGetArticleListFail)
		return
	}

	response.ToResponseList(articles, totalRows)
	return
}

// Create 新增文章
// @Summary 新增文章
// @Produce json
// @Param name body string true "文章名称" minlength(3) maxlength(100)
// @Param state body int false "状态" Enums(0, 1) default(1)
// @Param create_by body string true "创建者" minlength(3) maxlength(100)
// @Success 200 {object} model.ArticleSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/Articles [post]
func (a Article) Create(ctx *gin.Context) {
	param := service.CreateArticleRequest{}
	response := app.NewResponse(ctx)
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		global.Logger.Errorf(ctx, "app.BindAndValid errs: %v", errs)
		errRsp := errcode.InvalidParams.WithDetails(errs.Errors()...)
		response.ToErrorResponse(errRsp)
		return
	}

	svc := service.New(ctx.Request.Context())
	err := svc.CreateArticle(&param)
	if err != nil {
		global.Logger.Errorf(ctx, "svc.CreateArticle err: %v\n", err)
		response.ToErrorResponse(errcode.ErrorCreateArticleFail)
		return
	}

	response.ToResponse(gin.H{})
	return
}

// Update 更新文章
// @Summary 更新文章
// @Produce json
// @Param id path int true "文章 ID"
// @Param name body string false "文章名称" maxlength(3) maxlength(100)
// @Param state body int false "状态" Enums(0, 1) default(1)
// @Param modified_by body string true "修改者" minlength(3) maxlength(100)
// @Success 200 {object} model.ArticleSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/Articles/{id} [put]
func (a Article) Update(ctx *gin.Context) {
	param := service.UpdateArticleRequest{
		ID: convert.StrTo(ctx.Param("id")).MustUInt32(),
	}
	response := app.NewResponse(ctx)
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		global.Logger.Errorf(ctx, "app.BindAndValid errs: %v\n", errs)
		errRsp := errcode.InvalidParams.WithDetails(errs.Errors()...)
		response.ToErrorResponse(errRsp)
		return
	}

	svc := service.New(ctx.Request.Context())
	err := svc.UpdateArticle(&param)
	if err != nil {
		global.Logger.Errorf(ctx, "svc.UpdateArticle err: %v\n", err)
		response.ToErrorResponse(errcode.ErrorUpdateArticleFail)
		return
	}

	response.ToResponse(gin.H{})
	return
}

// Delete 删除文章
// @Summary 删除文章
// @Produce json
// @Param id path int true "文章 ID"
// @Success 200 {object} model.ArticleSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/Articles/{id} [delete]
func (a Article) Delete(ctx *gin.Context) {
	param := service.DeleteArticleRequest{
		ID: convert.StrTo(ctx.Param("id")).MustUInt32(),
	}
	response := app.NewResponse(ctx)
	valid, errs := app.BindAndValid(ctx, &param)
	if !valid {
		global.Logger.Errorf(ctx, "app.BindAndValid errs: %v\n", errs)
		errRsp := errcode.InvalidParams.WithDetails(errs.Errors()...)
		response.ToErrorResponse(errRsp)
	}

	svc := service.New(ctx.Request.Context())
	err := svc.DeleteArticle(&param)
	if err != nil {
		global.Logger.Errorf(ctx, "svc.DeleteArticle err: %v\n", err)
		response.ToErrorResponse(errcode.ErrorDeleteArticleFail)
		return
	}
	response.ToResponse(gin.H{})
	return
}
